package com.example.hinfc;

import android.content.Intent;
import android.nfc.cardemulation.HostApduService;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import java.util.Arrays;

public class HceService extends HostApduService {
    private static final String TAG = "HceService";
    private static final String AID = "F0010203040506";

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate success");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand success");
        return super.onStartCommand(intent, flags, startId);
    }

    // 当NFC读取器向服务发送应用协议数据单元 (APDU)时就会调用
    @Override
    public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
        Log.e(TAG, "processCommandApdu....");

        if (commandApdu == null) {
            Toast.makeText(this, "commandApdu == null", Toast.LENGTH_SHORT).show();
            Log.e("HceService", "commandApdu == null");
            return new byte[0];
        }

        Log.i(TAG, "commandApdu = " + Arrays.toString(commandApdu));

        int cla = commandApdu[0] & 0xFF;
        int ins = commandApdu[1] & 0xFF;

        if (cla == 0x00) {
            switch (ins) {
                case 0xA4: // SELECT
                    return handleSelect(commandApdu);
                case 0xB0: // PAYMENT
                    return handlePayment(commandApdu);
            }
        }

        Toast.makeText(this, "Unknown command" + commandApdu.toString(), Toast.LENGTH_SHORT).show();
        return new byte[]{0x6A, 0x00}; // Unknown command
    }

    private byte[] handleSelect(byte[] apdu) {
        Log.i(TAG, "handleSelect...");

        int aidLength = apdu[4] & 0xFF;
        byte[] receivedAid = Arrays.copyOfRange(apdu, 5, 5 + aidLength);
        byte[] targetAid = hexStringToByteArray(AID);

        if (Arrays.equals(receivedAid, targetAid)) {
            Log.i(TAG, "handleSelect...success");
            Toast.makeText(this, "handleSelect...success", Toast.LENGTH_SHORT).show();
            return new byte[]{ (byte) 0x90, 0x00 }; // OK
        } else {
            Log.i(TAG, "handleSelect...file not find");
            return new byte[]{0x6A, (byte) 0x82}; // File not found
        }
    }

    private byte[] handlePayment(byte[] apdu) {
        Log.i(TAG, "handlePayment...");

        int dataLength = apdu[4] & 0xFF;
        byte[] amountBytes = Arrays.copyOfRange(apdu, 5, 5 + dataLength);
        int amount = Integer.parseInt(new String(amountBytes));

        Log.i(TAG, "amount = " + amount);
        Toast.makeText(this, "pay success!! amount = " + amount, Toast.LENGTH_SHORT).show();
        return new byte[]{ (byte) 0x90, 0x00 };
    }

    private byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }

    @Override
    public void onDeactivated(int reason) {}

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy...");
    }
}
